package com.tmian.aiagent.app;

import com.tmian.aiagent.Advisor.MyLoggerAdvisor;
import com.tmian.aiagent.ChatMemory.FileBasedChatMemory;
import com.tmian.aiagent.record.DelicaciesRecord;
import com.tmian.aiagent.toolsResgister.ToolRegistration;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.api.Advisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@Component
public class DelicaciesApp {

    private static final Logger log = LoggerFactory.getLogger(DelicaciesApp.class);
    private ChatClient chatClient;


    private static final String SYSTEM_PROMPT = "你是一位资深美食探索家，拥有10年全球美食探店与烹饪研究经验。" +
            "你精通各类菜系文化，擅长推荐个性化美食，并帮助用户解决烹饪难题。" +
            "你的风格亲切专业，善于用生动的描述激发用户对美食的兴趣。" +
            "你能为用户提供美食的查找及地域美食的建议";

    @Resource
    VectorStore delicaciesVectorStore;

    @Resource
    Advisor delicaciesAppRagCloudAdvisor;

    @Resource
    ToolRegistration alltools;

    public DelicaciesApp(ChatModel DashscopechatModel) {

        // 初始化基于内存的对话记忆
        String fileDir = System.getProperty("user.dir") + "/chat-memory";
        FileBasedChatMemory chatMemory = new FileBasedChatMemory(fileDir);
        this.chatClient = ChatClient.builder(DashscopechatModel)
                .defaultSystem(SYSTEM_PROMPT)
                .defaultAdvisors(
                        new MessageChatMemoryAdvisor(chatMemory),
                        new MyLoggerAdvisor()
                )
                .build();
    }

    //对话方法
    public String doChat(String message, String chatId) {
        ChatResponse chatResponse = chatClient.prompt()
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
                .user(message)
                .call()
                .chatResponse();

        String result = chatResponse.getResult().getOutput().getText();
        log.info("result: {}", result);
        return result;
    }

    //输出实例对象的对话方法
    public DelicaciesRecord doChatWithRecord(String message, String chatId) {
        DelicaciesRecord record = chatClient.prompt()
                .system(SYSTEM_PROMPT + "每次对话后都要生成美食记录，标题为{用户名}的美食报告，内容为建议列表")
                .user(message)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
                .call()
                .entity(DelicaciesRecord.class);

        log.info("DelicaciesRecord: {}", record);
        return record;
    }

    //知识库对话
    public String doChatWithRag(String message, String chatId) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(message)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
//                .advisors(new QuestionAnswerAdvisor(delicaciesVectorStore))
                .advisors(delicaciesAppRagCloudAdvisor)
                .call()
                .chatResponse();

        String result = chatResponse.getResult().getOutput().getText();
        log.info("result: {}", result);
        return result;
    }

    //工具对话
    public String doChatWithTools(String message, String chatId) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(message)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
                .advisors(new QuestionAnswerAdvisor(delicaciesVectorStore))
                .tools(alltools)
                .call()
                .chatResponse();

        String result = chatResponse.getResult().getOutput().getText();
        log.info("result: {}", result);
        return result;
    }

    //mcp对话
    @Resource
    private ToolCallbackProvider toolCallbackProvider;

    public String doChatWithMcp(String message, String chatId) {
        ChatResponse chatResponse = chatClient.prompt()
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
                .user(message)
                .tools(toolCallbackProvider)
                .call()
                .chatResponse();

        String result = chatResponse.getResult().getOutput().getText();
        log.info("result: {}", result);
        return result;
    }


    //流式输出
    public Flux<String> doChatByStream(String message, String chatId) {
        Flux<String> content = chatClient.prompt()
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)
                )
                .user(message)
                .stream()
                .content();

        return content;
    }
}
